package com.spx.kernel.ui.widgets;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;

//import com.spx.core.wizards.ModelLabelProvider;
import com.spx.kernel.types.ModelType;

public class DoubleListSelector<T extends ModelType> extends Composite
{

	Set<T> chosen;
	Set<T> avaliable;
	final private TableViewer availableViewer;
	final private TableViewer chosenViewer;

	public DoubleListSelector(Composite parent, int style, Set<T> available, Set<T> initailChosen)
	{
		super(parent, style);
		this.avaliable = Collections.unmodifiableSet(available);
		chosen = new HashSet<T>();
		chosen.addAll(initailChosen);

		final String chosenTitle = "Selected";
		final String availableTitle = "Available";

		final GridLayout layout = new GridLayout();
		layout.numColumns = 3;

		if (available.containsAll(chosen) == false && chosen.isEmpty() == false)
		{
			throw new IllegalArgumentException("the Chosen set is not  a  subset of the available");
		}

		setLayout(layout);
		availableViewer = createViewer(availableTitle);
		createChoiceButtons();
		chosenViewer = createViewer(chosenTitle);
		chosenViewer.setContentProvider(getChosenContentProver());
		availableViewer.setContentProvider(getAvailableContentProver());

		availableViewer.setInput(available);
		chosenViewer.setInput(chosen);
	}

	private void createChoiceButtons()
	{
		final Composite choiceButtons = new Composite(this, SWT.NONE);

		final GridData gd = new GridData();
		gd.verticalAlignment = SWT.CENTER;
		gd.grabExcessHorizontalSpace = true;
		choiceButtons.setLayoutData(gd);
		final GridLayout buttonLayout = new GridLayout(1, false);

		choiceButtons.setLayout(buttonLayout);

		final GridData bgd = new GridData();
		bgd.grabExcessHorizontalSpace = true;
		bgd.horizontalAlignment = SWT.FILL;

		final Button choose = new Button(choiceButtons, SWT.NONE);
		choose.setLayoutData(bgd);
		final Button unChoose = new Button(choiceButtons, SWT.NONE);
		unChoose.setLayoutData(bgd);
		final Button chooseAll = new Button(choiceButtons, SWT.NONE);
		chooseAll.setLayoutData(bgd);
		final Button unChooseAll = new Button(choiceButtons, SWT.NONE);
		unChooseAll.setLayoutData(bgd);
		choose.setText(">");
		unChoose.setText("<");
		chooseAll.setText(">>");
		unChooseAll.setText("<<");
		choiceButtons.pack();
		choose.addSelectionListener(new SelectionAdapter()
		{
			@Override
			public void widgetSelected(SelectionEvent event)
			{
				final IStructuredSelection selection = (IStructuredSelection) availableViewer.getSelection();

				for (final Object object : selection.toArray())
				{
					final T model = (T) object;
					chosen.add(model);
					availableViewer.refresh();
					chosenViewer.refresh();
				}

			}
		});

		chooseAll.addSelectionListener(new SelectionAdapter()
		{
			@Override
			public void widgetSelected(SelectionEvent event)
			{
				chosen.addAll(avaliable);
				availableViewer.refresh();
				chosenViewer.refresh();

			}
		});

		unChoose.addSelectionListener(new SelectionAdapter()
		{
			@Override
			public void widgetSelected(SelectionEvent event)
			{
				final IStructuredSelection selection = (IStructuredSelection) chosenViewer.getSelection();

				for (final Object object : selection.toArray())
				{
					final ModelType model = (ModelType) object;
					chosen.remove(model);
					availableViewer.refresh();
					chosenViewer.refresh();
				}

			}
		});

		unChooseAll.addSelectionListener(new SelectionAdapter()
		{
			@Override
			public void widgetSelected(SelectionEvent event)
			{
				chosen.clear();
				availableViewer.refresh();
				chosenViewer.refresh();

			}
		});

	}

	private TableViewer createViewer(final String chosenTitle)
	{

		final GridData tableGridData = getTableGridData();
		final Group group = new Group(this, SWT.NONE);

		group.setText(chosenTitle);
		group.setLayoutData(tableGridData);
		group.setLayout(new GridLayout());
		final TableViewer viewer = new TableViewer(group, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
		viewer.getTable().setLayoutData(tableGridData);
		final ModelLabelProvider labelProvider = new ModelLabelProvider();
		viewer.setLabelProvider(labelProvider);
		viewer.setSorter(new NameSorter());
		return viewer;
	}

	private GridData getTableGridData()
	{
		final GridData gdt = new GridData();
		gdt.verticalAlignment = SWT.FILL;
		gdt.grabExcessVerticalSpace = true;
		gdt.grabExcessHorizontalSpace = true;
		gdt.heightHint = 200;
		gdt.widthHint = 200;
		return gdt;
	}

	public IStructuredContentProvider getAvailableContentProver()
	{
		return new IStructuredContentProvider()
		{

			public void inputChanged(Viewer v, Object oldInput, Object newInput)
			{

			}

			public void dispose()
			{
			}

			public Object[] getElements(Object parent)
			{
				final Set<ModelType> exclusiveAvailable = new HashSet<ModelType>(avaliable);
				exclusiveAvailable.removeAll(chosen);
				return exclusiveAvailable.toArray();

			}
		};
	}

	public IStructuredContentProvider getChosenContentProver()
	{
		return new IStructuredContentProvider()
		{

			public void inputChanged(Viewer v, Object oldInput, Object newInput)
			{

			}

			public void dispose()
			{
			}

			public Object[] getElements(Object parent)
			{
				return chosen.toArray();
			}
		};
	}

	public Set<T> getChosen()
	{
		return chosen;
	}

}
